﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Model;
using ME = Model.Environment;

namespace Zellularautomat
{
	/// <summary>
	/// Interaktionslogik für WindowTrajectory.xaml
	/// </summary>
	public partial class WindowTrajectory : Window
	{
		Dictionary<CellDefinition, ObservableDataSource<Point>> sources = new Dictionary<CellDefinition, ObservableDataSource<Point>>();
		private Dictionary<CellDefinition, Color> colorsForCells;

		public WindowTrajectory(Dictionary<CellDefinition, Color> colorsForCells)
		{
			this.colorsForCells = colorsForCells;
			InitializeComponent();
		}

		private void Window_Initialized(object sender, System.EventArgs e)
		{
			plotter.Legend.LegendLeft = 10.0;
			plotter.Legend.LegendRight = double.NaN;
			Init();

			ME.Trajectory.NextStep += Trajectory_NextStep;
		}

		void Trajectory_NextStep(object sender, TrajectoryChangedEventArgs e)
		{
			foreach (var line in this.sources)
			{
				line.Value.AppendAsync(this.Dispatcher, e.CurrentPoints[line.Key]);
			}
		}

		void linegraph_DataChanged(object sender, EventArgs e)
		{
			LineGraph lineGraph = (LineGraph)sender;
			double y = Enumerable.LastOrDefault<Point>(DataSourceExtensions.GetPoints(lineGraph.DataSource)).Y;
			lineGraph.Description = (Description)new PenDescription(string.Format("{0} {1:0%}", (CellDefinition)lineGraph.Tag, y));
		}

		private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			e.Cancel = true;
			this.Hide();
		}

		public void Initialize(Dictionary<CellDefinition, Color> colorsForCells)
		{
			this.colorsForCells = colorsForCells;
			Init();
		}

		private void Init()
		{
			this.sources = new Dictionary<CellDefinition, ObservableDataSource<Point>>();
			this.plotter.Children.RemoveAll(typeof(LineGraph));
			foreach (var cd in ME.CellDefinitions.Values)
			{
				this.sources.Add(cd, new ObservableDataSource<Point>());
				this.sources[cd].SetXYMapping((Func<Point, Point>)(p => p));
				LineGraph linegraph = Plotter2DExtensions.AddLineGraph((Plotter2D)this.plotter, (IPointDataSource)this.sources[cd], colorsForCells[cd], 2.0, cd.ToString());
				linegraph.Tag = cd;
				linegraph.DataChanged += linegraph_DataChanged;
				for (int i = 0; i < ME.Trajectory.TimeStamp; i++)
				{
					this.sources[cd].AppendAsync(this.Dispatcher, new Point(i, ME.Trajectory[cd][i]));
				}
			}
		}
	}
}
